package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.itheima.autoconfig.aip.AipFaceTemplate;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.vo.UserInfoVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component // controller的业务处理类
public class UserManager {

    @Reference //远程注入的对象
    private UserService userService;
    //根据手机号查询用户对象  糊涂工具包
    public User findByPhone(String phone) {

        return userService.findByPhone(phone);
    }

    @Autowired
    private HuanXinTemplate huanXinTemplate;
    //保存用户
    public Long save(User user) {
        //加密
        String md5Password = SecureUtil.md5(user.getPassword());
        user.setPassword(md5Password);
        Long id = userService.save(user);

        //保存用户后 可以注册环信
        //huanXinTemplate.register(id); //todo 以后项目上线需要将环信注册打开
        return id;
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //发送短信验证码
    public User sendSms(String phone) {
        //1.生成验证码
        //String code = RandomUtil.randomNumbers(6);

        //TODO 验证码写死  以后需要更改
        String code = "123456";
        //2.存入redis  超时时间5分钟
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone ,code , Duration.ofMinutes(5));
        return null;
    }


    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     * 注册或者登录
     */
    public Map regOrLogin(String phone, String verificationCode) {
        //1.获得redis中验证码 进行对比
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        if( !StrUtil.equals(redisCode , verificationCode) ){ //判断是否相等
            throw  new RuntimeException("验证码输入错误");
        }
        //当操作完code 之后 要删除缓存的验证码
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);


        //2.对比成功执行查询用户
        User user = userService.findByPhone(phone);

        String type= "0101"; //默认登录
        boolean  isNew = false ; //表示 是不是新用户
        if(user != null){
            //3.查询到  执行登录
            isNew = false;
        }else{
            //4.查询不到 执行注册
            isNew = true;
            //新用户 创建对象
            user = new User();
            user.setPhone(phone); //手机号
            user.setPassword(ConstantUtil.INIT_PASSWORD);//密码
            //userService.save(user);//注册用户
            Long id = save(user);//UserManager提供好的方法
            user.setId(id); //重新赋值id
            type = "0102";
        }
        //error 红字
        System.err.println("--->>>>"+user.getId());
        //5.将数据放入redis - 用户信息 存入token
        Map<String , Object> tokenMap = new HashMap<>();
        tokenMap.put("id" , user.getId()) ;
        tokenMap.put("phone" , user.getPhone()) ;
        String token = JwtUtil.createToken(tokenMap);

        //将登录数据放入缓存 并且设置时效性为30天 //第二次访问叫续期
        //token的值无所谓, key就已经是唯一的 key已经包含用户数据
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token , "1" ,Duration.ofDays(30) );


        //日志
        Log log = new Log();
        log.setUserId(user.getId());//用户id
        log.setLogTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));//操作时间
        log.setPlace("北京");//操作地点
        log.setEquipment("小米9");//操作设备  前端要传
        log.setType(type);//操作类型
        //发送数据
        rocketMQTemplate.convertAndSend("tanhua-log",log);



        //6.构建返回值
        Map<String ,Object> returnMap = new HashMap<>();
        returnMap.put("token" , token);
        returnMap.put("isNew" , isNew);
        return returnMap;
    }


    @Reference
    private UserInfoService userInfoService;
    //保存userInfo的方法
    public Map saveUserInfo(UserInfo userInfo) {
        userInfoService.save(userInfo);
        return null;
    }

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;
    //头像上传
    public Map updateUserInfo(MultipartFile headPhoto,Long id) throws IOException {
        //1.识别图片
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if(!detect){
            throw new RuntimeException("对不起,识别不到人脸");
        }

        //2.OSS存储
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        System.out.println(url);

        //3.存储到数据库
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setAvatar("https://"+url); // 头像或朋友圈背景图
        userInfo.setCoverPic("https://"+url); // 头像或朋友圈背景图
        userInfoService.update(userInfo);
        return null;
    }

    //根据传入的id 返回用户对象信息
    public UserInfoVo findById(Long id) {
        //1.根据传入id查询用户信息
        UserInfo userInfo = userInfoService.findById(id);
        //2.创建Vo对象(专门给前端页面使用)
        UserInfoVo vo = new UserInfoVo();
        //3.转换动作 source 数据源的来源  target 去往的目标
        BeanUtil.copyProperties(userInfo , vo);
        //4.注意age
        return vo;
    }

    //修改用户的个人资料
    public Map updateUserInfoById(UserInfo userInfo) {
        System.out.println("===>>"+userInfo);
        userInfoService.update(userInfo);
        return null;
    }
}
